use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::{RwLock, mpsc, Mutex};
use tokio::task::JoinHandle;
use tracing::{info, error, warn, debug};
use chrono::{DateTime, Utc};

use crate::config::ConfigManager;
use crate::modbus::{ModbusClientManager, DataParser};
use crate::storage::{DataStorage, DataPoint, DataQuality};
use crate::collector::{TaskScheduler, CollectionTask};
use crate::error::{Result, ModbusCollectorError};

/// 数据采集引擎
#[derive(Debug)]
pub struct DataCollector {
    config_manager: ConfigManager,
    modbus_manager: ModbusClientManager,
    storage: DataStorage,
    scheduler: TaskScheduler,
    task_receiver: Arc<Mutex<mpsc::UnboundedReceiver<CollectionTask>>>,
    running: Arc<RwLock<bool>>,
    worker_handles: Vec<JoinHandle<()>>,
}

impl DataCollector {
    pub async fn new(config_manager: ConfigManager, storage: DataStorage) -> Result<Self> {
        let modbus_manager = ModbusClientManager::new();
        let (task_sender, task_receiver) = mpsc::unbounded_channel();
        let scheduler = TaskScheduler::new(config_manager.clone(), task_sender);
        
        Ok(Self {
            config_manager,
            modbus_manager,
            storage,
            scheduler,
            task_receiver: Arc::new(Mutex::new(task_receiver)),
            running: Arc::new(RwLock::new(false)),
            worker_handles: Vec::new(),
        })
    }
    
    /// 启动数据采集器
    pub async fn start(&mut self) -> Result<()> {
        info!("Starting data collector");
        
        *self.running.write().await = true;
        
        // 启动任务调度器
        self.scheduler.start().await?;
        
        // 启动工作线程池
        self.start_workers().await?;
        
        info!("Data collector started successfully");
        Ok(())
    }
    
    /// 停止数据采集器
    pub async fn stop(&mut self) -> Result<()> {
        info!("Stopping data collector");
        
        *self.running.write().await = false;
        
        // 等待所有工作线程完成
        for handle in self.worker_handles.drain(..) {
            if let Err(e) = handle.await {
                error!("Worker thread error during shutdown: {}", e);
            }
        }
        
        // 断开所有Modbus连接
        self.modbus_manager.disconnect_all().await;
        
        info!("Data collector stopped");
        Ok(())
    }
    
    /// 启动工作线程
    async fn start_workers(&mut self) -> Result<()> {
        let worker_count = 4; // 可配置的工作线程数量
        
        for i in 0..worker_count {
            let running = self.running.clone();
            let modbus_manager = self.modbus_manager.clone();
            let storage = self.storage.clone();
            let task_receiver = self.task_receiver.clone();
            
            let handle = tokio::spawn(async move {
                info!("Worker {} started", i);
                
                while *running.read().await {
                    tokio::select! {
                        _ = async {
                            let mut receiver = task_receiver.lock().await;
                            match receiver.recv().await {
                                Some(collection_task) => {
                                    drop(receiver); // 释放锁
                                    if let Err(e) = Self::execute_collection_task(
                                        &modbus_manager,
                                        &storage,
                                        collection_task
                                    ).await {
                                        error!("Collection task execution failed: {}", e);
                                    }
                                },
                                None => {
                                    debug!("Task receiver closed in worker {}", i);
                                    return;
                                }
                            }
                        } => {},
                        _ = tokio::time::sleep(Duration::from_millis(100)) => {
                            // 定期检查是否需要停止
                        }
                    }
                }
                
                info!("Worker {} stopped", i);
            });
            
            self.worker_handles.push(handle);
        }
        
        info!("Started {} worker threads", worker_count);
        Ok(())
    }
    
    /// 执行采集任务
    async fn execute_collection_task(
        modbus_manager: &ModbusClientManager,
        storage: &DataStorage,
        task: CollectionTask,
    ) -> Result<()> {
        debug!("Executing collection task for device: {}", task.device_id);
        
        let start_time = std::time::Instant::now();
        let mut success_count = 0;
        let mut error_count = 0;
        
        // 按地址分组点位以优化读取
        let grouped_points = Self::group_points_by_address(&task.points);
        
        for (address_range, points) in grouped_points {
            match Self::read_point_group(
                modbus_manager,
                &task.device_config,
                &points,
                address_range
            ).await {
                Ok(data_points) => {
                    // 存储成功读取的数据
                    for data_point in data_points {
                        if let Err(e) = storage.store_data_point(&data_point).await {
                            error!("Failed to store data point {}: {}", data_point.point_id, e);
                            error_count += 1;
                        } else {
                            success_count += 1;
                        }
                    }
                },
                Err(e) => {
                    error!("Failed to read point group for device {}: {}", task.device_id, e);
                    error_count += points.len();
                }
            }
        }
        
        let duration = start_time.elapsed();
        
        if error_count > 0 {
            warn!("Collection task for device {} completed with errors: {} success, {} errors, took {:?}",
                  task.device_id, success_count, error_count, duration);
        } else {
            debug!("Collection task for device {} completed successfully: {} points, took {:?}",
                   task.device_id, success_count, duration);
        }
        
        Ok(())
    }
    
    /// 读取点位组
    async fn read_point_group(
        modbus_manager: &ModbusClientManager,
        device_config: &crate::config::DeviceConfig,
        points: &[crate::config::PointConfig],
        address_range: (u16, u16),
    ) -> Result<Vec<DataPoint>> {
        let mut data_points = Vec::new();
        let now = Utc::now();
        
        // 计算需要读取的寄存器数量
        let start_addr = address_range.0;
        let count = address_range.1 - address_range.0 + 1;
        
        // 读取原始数据
        let raw_data = modbus_manager.read_point_data(
            device_config,
            &points[0] // 使用第一个点位确定读取类型
        ).await?;
        
        // 解析每个点位的数据
        for point in points {
            let offset = (point.address - start_addr) as usize;
            
            // 根据数据类型确定需要的寄存器数量
            let register_count = match point.data_type {
                crate::config::DataType::Bool | 
                crate::config::DataType::Int16 | 
                crate::config::DataType::UInt16 => 1,
                crate::config::DataType::Int32 | 
                crate::config::DataType::UInt32 | 
                crate::config::DataType::Float32 => 2,
                crate::config::DataType::Float64 => 4,
            };
            
            if offset + register_count <= raw_data.len() {
                let point_data = &raw_data[offset..offset + register_count];
                
                match DataParser::parse_data(point_data, point) {
                    Ok(value) => {
                        let data_point = DataPoint {
                            point_id: point.point_id.clone(),
                            device_id: point.device_id.clone(),
                            name: point.name.clone(),
                            value,
                            timestamp: now,
                            quality: DataQuality::Good,
                        };
                        data_points.push(data_point);
                    },
                    Err(e) => {
                        error!("Failed to parse data for point {}: {}", point.point_id, e);
                        let data_point = DataPoint {
                            point_id: point.point_id.clone(),
                            device_id: point.device_id.clone(),
                            name: point.name.clone(),
                            value: 0.0,
                            timestamp: now,
                            quality: DataQuality::Bad,
                        };
                        data_points.push(data_point);
                    }
                }
            } else {
                error!("Insufficient data for point {}", point.point_id);
                let data_point = DataPoint {
                    point_id: point.point_id.clone(),
                    device_id: point.device_id.clone(),
                    name: point.name.clone(),
                    value: 0.0,
                    timestamp: now,
                    quality: DataQuality::Bad,
                };
                data_points.push(data_point);
            }
        }
        
        Ok(data_points)
    }
    
    /// 按地址分组点位以优化读取
    fn group_points_by_address(points: &[crate::config::PointConfig]) -> HashMap<(u32, u32), Vec<crate::config::PointConfig>> {
        let mut groups = HashMap::new();
        
        // 简单实现：每个点位单独读取
        // TODO: 实现智能分组，合并连续地址的点位
        for point in points {
            let register_count = match point.data_type {
                crate::config::DataType::Bool | 
                crate::config::DataType::Int16 | 
                crate::config::DataType::UInt16 => 1,
                crate::config::DataType::Int32 | 
                crate::config::DataType::UInt32 | 
                crate::config::DataType::Float32 => 2,
                crate::config::DataType::Float64 => 4,
            };
            
            let start_addr = point.address;
            let end_addr = start_addr + register_count - 1;
            let range = (start_addr, end_addr);
            
            groups.entry(range).or_insert_with(Vec::new).push(point.clone());
        }
        
        groups
    }
    
    /// 获取采集器状态
    pub async fn get_status(&self) -> CollectorStatus {
        CollectorStatus {
            running: *self.running.read().await,
            worker_count: self.worker_handles.len(),
            task_status: self.scheduler.get_task_status().await,
        }
    }
    
    /// 重新加载配置
    pub async fn reload_config(&self) -> Result<()> {
        info!("Reloading collector configuration");
        self.scheduler.reload_tasks().await
    }
}

/// 采集器状态
#[derive(Debug, Clone)]
pub struct CollectorStatus {
    pub running: bool,
    pub worker_count: usize,
    pub task_status: HashMap<String, crate::collector::TaskStatus>,
}

impl Clone for DataCollector {
    fn clone(&self) -> Self {
        // 注意：这里克隆的是引用，实际的DataCollector应该是单例
        panic!("DataCollector should not be cloned directly. Use Arc<DataCollector> instead.");
    }
}